﻿#ifndef QLIB_HEADER_FAN
#define QLIB_HEADER_FAN

#include "qlib/core/object.h"
#include "qlib/core/vec2.h"
#include "qlib/geo/polygon.h"
#include "qlib/layout/repetition.h"
#include "qlib/layout/property.h"

namespace qlib {
enum struct GeoPartType;

class Fan;
using FanPtrArray = std::vector<std::shared_ptr<Fan>>;
// 0: 中心， 1: 顶点， 2: 边， 3: 边中点，4: box顶点, 5: box边, 6: box边中心, 7: 扇形弧形中点， 8: 扇形弧形起点，9: 扇形弧形终点, 10: 扇形圆弧, 起始半径边， 终止半径边
using FanParts = std::tuple<Vec2d, Vec2dArray, std::vector<Vec2dArray>, Vec2dArray, Vec2dArray, std::vector<Vec2dArray>, Vec2dArray, Vec2d, Vec2d,
                            Vec2d, Vec2dArray, Vec2dArray, Vec2dArray>;

class QLIB_API Fan {
 public:
  Fan();
  Fan(Vec2d _center, double _radius, Vec2d _angle, float _rotation, double _tolerance = 1e-3, uint32_t _layer = 0, uint32_t _datatype = 0);

  Fan(const Fan& oth);
  Fan& operator=(const Fan& other);

  using s_ptr = std::shared_ptr<Fan>;
  template <typename... Args>
  static s_ptr create(Args... args) {
    return std::make_shared<Fan>(args...);
  }
  // template <>
  static s_ptr create() {
    return std::make_shared<Fan>();
  }
  static s_ptr create(const Fan& value) { return std::make_shared<Fan>(value); }

  s_ptr copy() const;

  void init(Vec2d _center, double _radius, Vec2d _angle, float _rotation, double _tolerance = 1e-3, uint32_t _layer = 0, uint32_t _datatype = 0);

  // 第一个为中心点，其他圆弧点
  Polygon::s_ptr to_polygon(bool is_tri = false);
  Vec2dArray bounding_box_points() { return box_to_points(bounding_box()); };
  Vec2dArray bounding_box();

  void scale(double s);
  void mirror(Vec2d p0, Vec2d p1);
  void translate(double dx, double dy);
  void rotate(double angle, qlib::Vec2d center);
  void transform(double magnification, bool x_reflection, Vec2d origin);
  double area() const;

  void transform(double magnification, bool x_reflection, double rotation, Vec2d origin);

  double getRotation();
  void setRotation(double rotation);

  Vec2d get_arc_center();
  Vec2d get_arc_start();
  Vec2d get_arc_end();

  // 部分选择
  FanParts get_parts();
  Vec2dArray query_parts(GeoPartType type, uint32_t id);

  // 渲染
  Vec2dArray render_aabb();
  Vec2dArray render_poly();
  Vec2dArray render_absorp();

  double getCenterAngle();
  void setCenterAngle(double angle);

  int getPointNum();
  void setPointNum(int num);

  Polygon::s_ptr polygon;

  mutable int point_num = 0;
  mutable double center_angle = 0;

  // 中心点
  Vec2d center{0.0, 0.0};

  // 半径
  double radius{0.0};

  // 起始角和中止角（x正半轴逆时针）
  Vec2d angle{0.0, 0.0};

  double tolerance{0.01};
  double rotation{0.0};

  uint32_t layer;
  uint32_t datatype;

  PropertyArray properties;
  Repetition repetition;

  Vec2dArray box{Vec2dArray(2)};
};

}  // namespace qlib

#endif